<template>
  <el-card class="box-card">
    <el-form ref="attr" :model="attr" :rules="rules">
      <!-- 输入属性名 -->
      <el-form-item label="属性名" prop="attrName" label-width="70px">
        <el-input v-model="attr.attrName" class="saveAttr-input" />
      </el-form-item>
      <el-form-item prop="attrValueList">
        <!-- 添加按钮 -->
        <el-button
          type="primary"
          :disabled="!attr.attrName"
          icon="el-icon-plus"
          class="saveAttr-btn"
          @click="handleSaveAttrValue"
        >
          添加属性值
        </el-button>
        <!-- 表格 -->
        <el-table
          :data="attr.attrValueList"
          border
          style="width: 100%"
          class="saveAttr-table"
        >
          <el-table-column
            type="index"
            align="center"
            label="序号"
            width="50px"
          />
          <el-table-column
            v-slot="{ row, $index }"
            prop="valueName"
            align="center"
            label="属性值名称"
          >
            <el-input
              v-show="row.isEdit"
              :ref="$index"
              v-model="row.valueName"
              size="mini"
              placeholder="请输入属性值名称"
              @blur="handleBlur(row, $index)"
            />
            <span
              v-show="!row.isEdit"
              class="saveAttr-span"
              @click="handleEdit(row, $index)"
            >
              {{ row.valueName }}
            </span>
          </el-table-column>
          <!-- scope:{
            row, 当前行数据
            $index 序号
          } -->
          <el-table-column v-slot="{ row, $index }" label="操作" align="center">
            <!-- 删除按钮 -->
            <el-popconfirm
              confirm-button-text="确定"
              cancel-button-text="取消"
              icon="el-icon-info"
              icon-color="red"
              title="确定删除吗？"
              @onConfirm="handleDelAttrValue($index)"
            >
              <el-tooltip
                slot="reference"
                effect="dark"
                content="删除属性"
                placement="top"
              >
                <el-button icon="el-icon-delete" type="danger" size="mini" />
              </el-tooltip>
            </el-popconfirm>
          </el-table-column>
        </el-table>
      </el-form-item>
    </el-form>

    <el-button type="primary" @click="handleSaveAttr">
      确 定
    </el-button>
    <el-button @click="$emit('showSaveAttr', false)">取 消</el-button>
  </el-card>
</template>

<script>
import { mapState } from 'vuex'
import { reqSaveAttrInfo } from '@/api/product/attr'

export default {
  name: 'SaveAttr',
  props: {
    // 修改属性时接收的数据
    editAttr: {
      type: Object,
      default: () => ({
        // 属性名
        attrName: '',
        // 增加的属性列表
        attrValueList: []
      })
    }
  },
  data() {
    // 自定义表单校验规则
    // rule 校验规则项
    // value 校验的表单项值
    // callback 必须调用的回调函数
    // callback() 校验通过 callback(xxx) 校验失败，xxx是失败的原因
    const validator = (rule, value, callback) => {
      if (value.length) {
        callback()
      } else {
        callback('请至少添加一个属性值')
      }
    }
    return {
      loading: false,
      attr: this.editAttr,
      // 表单校验规则
      rules: {
        attrName: [
          { required: true, message: '请输入属性名', trigger: 'blur' },
          { min: 1, max: 10, message: '长度在 1 到 10 个字符', trigger: 'blur' }
        ],
        // 引用类型需要自定义校验规则判断是否有值
        attrValueList: [{ required: true, validator }]
      }
    }
  },
  computed: {
    ...mapState('category', ['category3Id'])
  },
  methods: {
    // 添加属性值到属性值列表
    handleSaveAttrValue() {
      this.attr.attrValueList.push({
        valueName: '',
        // 默认初始可编辑
        isEdit: true
      })
      // 添加完成后在最新添加的属性值输入框中自动获取焦点
      // 因为更新是异步的，所以需要等dom元素完全渲染完再获取焦点，否则无法获取
      this.$nextTick(() => {
        this.$refs[this.attr.attrValueList.length - 1].focus()
      })
    },
    // 属性列表中输入框失去焦点时，判断是否有值
    handleBlur(row, index) {
      if (row.valueName) {
        row.isEdit = false
      } else {
        this.attr.attrValueList.splice(index, 1)
      }
    },
    // 将文本内容变为输入框并自动获取焦点
    handleEdit(row, index) {
      // 修改属性时传入的数据中不含isEdit属性，后面添加的isEdit不会成为响应式数据，
      // 需要使用$set将其添加为响应式数据
      this.$set(row, 'isEdit', true)
      // row.isEdit = true
      this.$nextTick(() => {
        this.$refs[index].focus()
      })
    },
    // 删除属性列表中的属性值
    handleDelAttrValue(index) {
      this.attr.attrValueList.splice(index, 1)
      this.$message({ type: 'success', message: '删除属性值成功' })
    },
    // 添加或修改商品属性
    handleSaveAttr() {
      this.$refs.attr.validate(async value => {
        if (value) {
          const { category3Id } = this
          const { attrName, attrValueList, id } = this.attr
          await reqSaveAttrInfo({
            attrName,
            attrValueList,
            categoryId: category3Id,
            categoryLevel: 3,
            // 无id时请求添加属性，有id时请求修改属性
            id
          })
          this.$emit('showSaveAttr', false)
          this.$message({
            type: 'success',
            message: `${id ? '修改' : '添加'}属性值成功`
          })
        }
      })
    }
  }
}
</script>

<style lang="scss" scoped>
.saveAttr-btn {
  margin-bottom: 20px;
}
.saveAttr-table {
  margin-bottom: 20px;
}
.saveAttr-input {
  width: 200px;
}
.saveAttr-span {
  display: block;
}
</style>
